import EvaluationRecord from '@/components/EvaluationRecord';
import GuidanceRecord from '@/components/GuidanceRecord';
import HealthRecords from '@/components/HealthRecords';
import PhysiologicalMonitoring from '@/components/PhysiologicalMonitoring';
import TrainingRecord from '@/components/TrainingRecord';
import {
  add_patient_callLog,
  edit_patient_callLog,
  guidance_Token,
  patient_callLog_list,
  patient_chat_call,
  patient_guidance_info,
  submit_patient_guidance,
} from '@/services/guide';
import { get_patient_info } from '@/services/patient';
import age from '@/utils/age';
import timeToHms from '@/utils/time';
import {
  ActionType,
  PageContainer,
  ProColumns,
  ProDescriptions,
  ProForm,
  ProTable,
} from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import AgoraRTC from 'agora-rtc-sdk-ng';
import AgoraRTM from 'agora-rtm-sdk';
import { Button, DatePicker, Divider, Form, message, Spin, Switch, Tabs } from 'antd';
import TextArea from 'antd/es/input/TextArea';
import dayjs from 'dayjs';
import moment from 'moment';
import { useEffect, useRef, useState } from 'react';
import './index.less';

var RTCclient: any;
var RTMclient: any;
var RTMchannel: any;
var my_uuid = '';
var to_uuid = '';
var channel = '';
var rtcToken = '';
var rtmToken = '';
//呼叫记录id
var chatlog_id = '';
var sid = '';
var resourceId = '';
//录制id
var record_uuid: number;
var start_time = '';
// 指导内容
var chat_content = '';
// 下次指导时间
var chat_time = moment(moment().day(moment().day() + 7)).format('YYYY-MM-DD');
// 下次指导备注
var remark = '';

// 用来放置本地音视频频轨道对象
var localAudioTrack: any;
var localVideoTrack: any;
const options = {
  appId: '268a993cd77249cf9f3c1e09a279e96c',
};
const videoConfig: any = {
  // 预设分辨率 默认 480p_1
  encoderConfig: '720p_1',
};
type GithubIssueItem = {
  id: number;
  time: string;
  call_type: number;
  create_time: string;
  status: number;
  status_d: string;
};
type Info = {
  family_address: string;
  area_name: string;
  city_name: string;
  province_name: string;
  birth: string;
  id: number;
  phone: string;
  username: string;
  sex: number;
  id_card: string;
  address: string;
  head_img: string;
  info: any;
};
const Audio = () => {
  const actionRef = useRef<ActionType>();
  // 获取URL参数
  const getUrlParam = (name: string) => {
    const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
    const r = window.location.search.substr(1).match(reg);
    if (r != null) {
      return decodeURIComponent(r[2]);
    }
    return null;
  };
  // 存储当前指导id
  const guideId: any = getUrlParam('id');
  // 存储患者id
  const patientId: any = getUrlParam('patient_id');
  // 存储患者信息
  const [patientinfo, setPatientInfo] = useState<any>(undefined);
  // 存储指导详情
  const [guideInfo, setGuideInfo] = useState<any>(undefined);
  // 当前用户详情
  const { initialState, setInitialState } = useModel('@@initialState');
  // 接听状态 用来处理 true显示拨打中倒计时/false显示已接通
  const [LocalInvitation, setLocalInvitation] = useState(true);
  // 取消呼叫loading状态
  const [cancelloading, setcancelloading] = useState(false);
  // 重新拨打loading状态
  const [callloading, setcallloading] = useState(false);
  // 通话状态 0未开始 1呼叫中 2通话中
  const [callstatus, setcallstatus] = useState(0);
  const call = useRef(callstatus);
  call.current = callstatus;
  // 呼叫倒计时秒 和 定时器
  const [times, settimes] = useState<any>(60);
  const timer: any = useRef();
  // 通话计时 和 计时器
  const [second, setsecond] = useState(0);
  const timemeter: any = useRef();
  const chatlog_second = useRef(second);
  chatlog_second.current = second;
  // 是否有有效的通话记录
  const [saveflag, setsaveflag] = useState(false);
  // 控制指导计划的显示与隐藏
  const [isShowPlan, setIsShowPlan] = useState(false);

  // 页面初始化
  useEffect(() => {
    //   页面初始化获取患者信息
    const getData = async () => {
      if (patientId) {
        let res: any = await get_patient_info({ id: patientId });
        console.log('患者详情', res);
        if (res.code === 200) {
          setPatientInfo(res.data);
        }
      }
    };
    // 获取指导详情信息
    const guideInfo = async () => {
      if (guideId) {
        let res: any = await patient_guidance_info({ id: guideId });
        console.log('指导详情', res);
        if (res.code == 200) {
          setGuideInfo(res.data);
        }
      }
    };
    getData();
    guideInfo();
    //   开始指导
    start_guide();
  }, []);

  // 监听页面刷新或关闭
  useEffect(() => {
    window.addEventListener('beforeunload', leave_Live_error);
    return () => {
      window.removeEventListener('beforeunload', leave_Live_error);
    };
  }, []);

  //接通倒计时
  const start_times = () => {
    console.log('接通倒计时');
    clearInterval(timer.current);
    timer.current = setInterval(() => {
      settimes((times: any) => {
        if (times > 0) {
          return times - 1;
        } else if (times == 0) {
          leave_Live();
          setcallstatus(0);
          return 60;
        }
      });
    }, 1000);
  };
  // 开始指导
  const start_guide = async () => {
    if (guideId) {
      let request_body = {
        id: Number(guideId),
        type: 1,
      };
      let res: any = await guidance_Token(request_body);
      console.log('指导频道和token', res);
      if (res.msg == 'ok') {
        channel = res.data.channel;
        my_uuid = res.data.uuid;
        to_uuid = res.data.to_uuid;
        rtcToken = res.data.rtctoken;
        rtmToken = res.data.rtmtoken;
        RTCclient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' });
        RTCclient.setClientRole('host');
        //   监听用户推流
        RTCclient.on('user-published', async (user: any, mediaType: any) => {
          await RTCclient.subscribe(user, mediaType);
          console.log('user-published', user, mediaType);
          if (mediaType == 'video') {
            return;
          }
          if (mediaType == 'audio') {
            // 订阅完成后，从 `user` 中获取远端音频轨道对象
            const remoteAudioTrack = user.audioTrack;
            // 播放音频因为不会有画面，不需要提供 DOM 元素的信息
            remoteAudioTrack.play();
          }
        });
        //   监听用户取消推流
        RTCclient.on('user-unpublished', async (user: any, mediaType: any) => {
          console.log('user-unpublished', user, mediaType);
          // 远端用户取消发布或离开频道
        });
        RTCclient.join(options.appId, res.data.channel, res.data.rtctoken, res.data.uuid).then(
          async () => {
            localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
            // localVideoTrack = await AgoraRTC.createCameraVideoTrack(videoConfig);
            await RTCclient.publish([localAudioTrack]);
          },
        );
        // 加入频道
        join(res.data.uuid, res.data.rtmtoken, res.data.channel, res.data.to_uuid);
      } else {
        message.error(res.msg);
      }
    }
  };
  // 加入RTM频道
  const join = async (uuid: number, rtmtoken: string, channel: string, to_uuid: number) => {
    console.log('to_uuid123456789', to_uuid);

    RTMclient = AgoraRTM.createInstance(options.appId);
    await RTMclient.login({ uid: uuid.toString(), token: rtmtoken });
    RTMchannel = RTMclient.createChannel(channel);
    await RTMchannel.join();
    // 订阅指导对象的登录状态
    RTMclient.subscribePeersOnlineStatus([String(to_uuid)]);
    // 监听指导对象的登录状态
    RTMclient.on('PeersOnlineStatusChanged', (message: any) => {
      // 选择拨打语音方式：在线使用RTM，不在线使用极光呼叫
      // call_type(message);
    });
    // 点对点消息，用来处理连麦生命周期 ， 接收挂断通知
    RTMclient.on('MessageFromPeer', async (message_n: any, peerId: number) => {
      console.log('message ', message_n, ' peerId', peerId);
      // 对方接受呼叫邀请
      if (
        message_n.messageType === 'TEXT' &&
        JSON.parse(message_n.text).type == 'phone_LocalInvitationAccepted' &&
        peerId == to_uuid
      ) {
        // 清除定时器
        clearInterval(timer.current);
        // 开始通话倒计时
        start_second();
        // 接听状态改为已接听
        setLocalInvitation(false);
        // //修改呼叫状态为呼叫中
        // setcallstatus(1);
        // 修改呼叫记录（通话中）
        edit_chatlog(1);
        //修改通话状态(2通话中)
        setcallstatus(2);
        message.warning('对方已接受呼叫邀请');
      }
      // 对方已拒绝呼叫邀请
      if (
        message_n.messageType === 'TEXT' &&
        JSON.parse(message_n.text).type == 'phone_LocalInvitationRefused' &&
        peerId == to_uuid
      ) {
        console.log('message ' + message_n.text + ' peerId' + peerId);
        // 修改取消呼叫loading状态
        setcancelloading(true);
        // 取消推流
        leave_Live('', 'reject');
        // 修改呼叫记录（已拒绝）
        edit_chatlog(2);
        //修改通话状态 (0未开始)
        setcallstatus(0);
        actionRef.current?.reload();
        message.warning('对方已拒绝呼叫邀请');
      }
      // 对方取消语音通话
      if (
        message_n.messageType === 'TEXT' &&
        JSON.parse(message_n.text).type == 'end_phone_NZwrJ043' &&
        peerId == to_uuid
      ) {
        console.log('message ' + message_n.text + ' peerId' + peerId);
        // 挂断
        await leave_Live('end', 'reject');
        setsecond(0);
        //通话状态 0未开始
        setcallstatus(0);
        actionRef.current?.reload();
        message.warning('对方已取消通话');
      }
    });
    chat_call(0);
  };

  //通话计时
  const start_second = () => {
    console.log('开始通话计时');
    clearInterval(timemeter.current);
    timemeter.current = setInterval(() => {
      setsecond((second) => {
        return second + 1;
      });
    }, 1000);
  };

  //获取呼叫记录
  const get_patient_callLog_list = async (params: {
    pageSize?: number | undefined;
    current?: number | undefined;
    keyword?: string | undefined;
  }) => {
    let request_body = {
      ...params,
      pcurrent: params.current,
      pageSize: params.pageSize,
      patient_guidance_id: guideId,
    };
    let res = await patient_callLog_list(request_body);
    console.log('呼叫记录', res);
    // actionRef.current?.reload();
    // 是否有有效通话记录
    setsaveflag(res.data.save_flag == 1);
    return {
      data: res.data.list,
      success: true,
      total: res.data.total_count,
    };
  };
  // 极光呼叫
  const chat_call = async (status: number) => {
    // 接通倒计时
    start_times();
    let request_body = {
      id: Number(guideId),
      type: 0,
      status,
      patient_id: Number(patientId),
    };
    let res: any = await patient_chat_call(request_body);
    console.log('极光呼叫', res);
    if (res.msg == 'ok') {
      // 新增一条呼叫记录
      let request_body = {
        patient_guidance_id: guideId,
        call_type: 0,
      };
      let params: any = await add_patient_callLog(request_body);
      if (params.msg == 'ok') {
        actionRef.current?.reload();
        //设置当前呼叫logid
        chatlog_id = params.data.id;
        //修改呼叫状态为呼叫中
        setcallstatus(1);
      }
    } else {
      message.error('呼叫失败');
    }
    setcallloading(false);
  };

  //修改当前呼叫状态
  const edit_chatlog = async (status: number) => {
    console.log('通话时长', chatlog_second.current, second);
    let request_body = {
      id: chatlog_id,
      status: status,
      time: chatlog_second.current,
    };
    let params = await edit_patient_callLog(request_body);
    console.log(params);
    actionRef.current?.reload();
    // edit_patient_callLog(request_body);
  };

  const error_edit_chatlog = async (status: number) => {
    let request_body = {
      id: chatlog_id,
      status: status,
      time: chatlog_second.current,
    };
    await edit_patient_callLog(request_body);
  };
  //关闭页面 异常退出挂断
  const leave_Live_error = () => {
    if (call.current == 1) {
      error_edit_chatlog(4);
    }
    if (call.current == 2) {
      error_edit_chatlog(3);
    }
    RTMclient.sendMessageToPeer(
      { text: JSON.stringify({ type: 'end_phone_NZwrJ043' }) },
      to_uuid.toString(),
    );

    window.opener.postMessage('refresh', '*');

    RTCclient = null;
  };

  // 正常退出、挂断
  const leave_Live = async (type?: any, status?: any) => {
    if (status != 'reject') {
      RTMclient.sendMessageToPeer(
        { text: JSON.stringify({ type: 'end_phone_NZwrJ043' }) },
        to_uuid.toString(),
      );
    }
    if (type == 'end') {
      edit_chatlog(3);
    }
    if (type == 'quit') {
      edit_chatlog(4);
    }
    window.opener.postMessage('refresh', '*');
    // 清除定时器
    clearInterval(timer.current);
    // 重置
    settimes(60);
    // 接听状态 显示拨打中倒计时
    setLocalInvitation(true);
    // 清除延时器
    clearInterval(timemeter.current);
    //退出RTC RTM 关闭页面

    RTMclient.logout();
    if (localAudioTrack) {
      localAudioTrack.close();
    }
    if (localVideoTrack) {
      localVideoTrack.close();
    }
    if (RTCclient) {
      await RTCclient.unpublish();
    }
    // 离开频道。
    await RTCclient.leave();
    RTCclient = null;

    //修改呼叫状态为未开始
    setcallstatus(0);
    setcancelloading(false);
  };

  //计时器格式化
  const studyTime = (t: number) => {
    let hour: any = Math.floor(t / 60 / 60);
    let minute: any = Math.floor((t / 60) % 60);
    let second: any = Math.floor(t % 60);
    if (hour < 10) {
      hour = '0' + hour;
    }
    if (minute < 10) {
      minute = '0' + minute;
    }
    if (second < 10) {
      second = '0' + second;
    }
    return hour + ':' + minute + ':' + second;
  };

  //修改指导记录
  const onChangecontent = (e: { target: { value: string } }) => {
    chat_content = e.target.value;
  };

  //修改下一次指导时间
  const onChangetime = (e: any) => {
    if (e !== null) {
      chat_time = moment(e).format('YYYY-MM-DD');
    } else {
      chat_time = e;
    }
  };

  // 修改备注
  const onChangeRemark = (e: { target: { value: string } }) => {
    remark = e.target.value;
  };

  // 结束指导
  const end_guide = async () => {
    if (chat_content.replace(/^\s\s*/, '').replace(/\s\s*$/, '') == '') {
      message.warning('请填写指导记录');
      return;
    }
    let request_body;
    if (isShowPlan) {
      if (chat_time == null) {
        message.warning('请选择下次计划指导时间');
        return;
      } else {
        request_body = {
          id: guideId,
          content: chat_content,
          plan_time: chat_time,
          remark: remark ?? remark,
        };
      }
    } else {
      request_body = {
        id: guideId,
        content: chat_content,
      };
    }
    let res: any = await submit_patient_guidance(request_body);
    if (res.msg == 'ok') {
      window.opener.postMessage('close', '*');
      message.success('指导已结束');
      setTimeout(() => {
        window.close();
      }, 500);
    } else {
      message.error(res.msg);
    }
  };

  // 通话记录
  const columns: ProColumns<GithubIssueItem>[] = [
    {
      title: '序号',
      dataIndex: 'index',
      valueType: 'index',
      hideInSearch: true,
      align: 'center',
    },
    {
      title: '通话时间',
      dataIndex: 'create_time',
      align: 'center',
    },
    {
      title: '通话方式',
      dataIndex: 'call_type',
      align: 'center',
      valueEnum: {
        0: {
          text: '语音',
        },
        1: {
          text: '视频',
        },
      },
    },
    {
      title: '通话时长',
      dataIndex: 'time',
      hideInSearch: true,
      align: 'center',
      render: (_, record) => {
        if (record.status != 3) {
          return record.status_d;
        } else {
          return timeToHms(record.time);
        }
      },
    },
  ];

  return (
    <PageContainer
      breadcrumb={false}
      header={{
        title: '患者详情',
        extra: [
          <Button key="end" type="primary" onClick={() => end_guide()} disabled={!LocalInvitation}>
            结束指导
          </Button>,
          <Button
            key="exit"
            onClick={() => {
              window.opener.postMessage('refresh', '*');
              setTimeout(() => {
                window.close();
              }, 500);
            }}
            disabled={!LocalInvitation}
          >
            返回
          </Button>,
        ],
      }}
    >
      <Divider />
      <div style={{ margin: '16px', padding: '0 24px', background: '#fff', minHeight: '600px' }}>
        {patientinfo === undefined && guideInfo === undefined ? (
          <div
            style={{
              margin: '20px 0',
              marginBottom: '20px',
              padding: '30px 50px',
              textAlign: 'center',
            }}
          >
            <Spin size="large" />
          </div>
        ) : (
          <>
            <div style={{ display: 'flex', width: '100%' }}>
              {LocalInvitation ? (
                callstatus == 1 ? (
                  <div className="call_box_phone">
                    <p style={{ marginTop: '50%', color: '#929292' }}>等待对方接听······</p>
                    {/* {times <= 55 ? ( */}
                    <Button
                      type="primary"
                      danger
                      onClick={() => {
                        // console.log('1');
                        setcancelloading(true);
                        leave_Live('quit');
                      }}
                      loading={cancelloading}
                    >
                      取消呼叫
                    </Button>
                    {/* ) : (
                      <></>
                    )} */}
                    <p style={{ marginTop: '20px', color: '#929292' }}>{times < 0 ? 0 : times} s</p>
                  </div>
                ) : (
                  <div className="call_box_phone">
                    <p style={{ marginTop: '50%', color: '#929292' }}>已取消通话</p>
                    <Button
                      type="primary"
                      danger
                      onClick={() => {
                        setcallloading(true);
                        start_guide();
                      }}
                      loading={callloading}
                    >
                      重新拨打
                    </Button>
                  </div>
                )
              ) : (
                <div className="call_box_phone">
                  <p>
                    <img
                      style={{
                        marginTop: '50%',
                        width: '80px',
                        height: '80px',
                        borderRadius: '50%',
                      }}
                      src={patientinfo.head_img}
                      alt=""
                    />
                  </p>
                  <p>{patientinfo.username}</p>
                  <p style={{ marginTop: '26%', color: '#929292' }}>通话中 {studyTime(second)}</p>

                  <button
                    style={{
                      background: 'red',
                    }}
                    onClick={async () => {
                      await leave_Live('end');
                      setsecond(0);
                    }}
                  >
                    挂断
                  </button>
                </div>
              )}

              <div style={{ flex: '1' }}>
                <ProDescriptions
                  dataSource={guideInfo}
                  columns={[
                    {
                      title: '手机号',
                      key: 'user_phone',
                      dataIndex: 'user_phone',
                    },
                    {
                      title: '姓名',
                      key: 'patient_name',
                      dataIndex: 'patient_name',
                    },
                    {
                      title: '性别',
                      key: 'patient_sex',
                      dataIndex: 'patient_sex',
                      valueType: 'select',
                      valueEnum: {
                        0: {
                          text: '未知',
                        },
                        1: {
                          text: '男',
                        },
                        2: {
                          text: '女',
                        },
                      },
                    },
                    {
                      title: '身份证号',
                      key: 'patient_idcard',
                      dataIndex: 'patient_idcard',
                    },
                    {
                      title: '年龄',
                      key: 'patient_birth',
                      dataIndex: 'patient_birth',
                      render: (_, record) => age(record.patient_birth),
                    },
                    {
                      title: '家庭地址',
                      key: 'patient_address',
                      dataIndex: 'patient_address',
                      render: (_, record) => {
                        return (
                          record.patient_province +
                          record.patient_ctiy +
                          record.patient_area +
                          record.patient_address
                        );
                      },
                    },
                  ]}
                ></ProDescriptions>
                <Tabs
                  defaultActiveKey="通话记录"
                  items={[
                    {
                      key: '通话记录',
                      label: '通话记录',
                      children: (
                        <ProTable<GithubIssueItem>
                          columns={columns}
                          actionRef={actionRef}
                          cardBordered
                          request={async (params = {}) => get_patient_callLog_list(params)}
                          editable={{
                            type: 'multiple',
                          }}
                          rowKey={(record) => record.id}
                          search={false}
                          options={false}
                          pagination={{
                            pageSize: 5,
                          }}
                          dateFormatter="string"
                          headerTitle=""
                        />
                      ),
                    },
                    {
                      key: '生理监测',
                      label: '生理监测',
                      children: (
                        <PhysiologicalMonitoring patientId={patientId}></PhysiologicalMonitoring>
                      ),
                    },
                    {
                      key: '评估记录',
                      label: '评估记录',
                      children: (
                        <EvaluationRecord type={false} patientId={patientId}></EvaluationRecord>
                      ),
                    },
                    {
                      key: '训练记录',
                      label: '训练记录',
                      children: <TrainingRecord patientId={patientId}></TrainingRecord>,
                    },
                    {
                      key: '指导记录',
                      label: '指导记录',
                      children: <GuidanceRecord patientId={patientId}></GuidanceRecord>,
                    },
                    {
                      key: '健康档案',
                      label: '健康档案',
                      children: <HealthRecords info={patientinfo?.info}></HealthRecords>,
                    },
                  ]}
                  // onChange={onChange}
                />
              </div>
            </div>
            <div style={{ display: 'flex' }}>
              <div style={{ width: '350px' }}>
                <ProForm
                  layout="horizontal"
                  labelCol={{ span: 9 }}
                  wrapperCol={{ span: 15 }}
                  submitter={{
                    searchConfig: {
                      submitText: '提交',
                      resetText: '重置',
                    },
                    resetButtonProps: {
                      style: {
                        // 隐藏重置按钮
                        display: 'none',
                        position: 'absolute',
                        left: 'calc(50% - 107px)',
                      },
                    },
                    submitButtonProps: {
                      style: {
                        display: 'none',
                        position: 'absolute',
                        right: 'calc(50% - 107px)',
                      },
                    },
                  }}
                >
                  <Form.Item name="status" label="下次指导计划">
                    <Switch
                      checkedChildren="开启"
                      unCheckedChildren="关闭"
                      defaultChecked={false}
                      onChange={(checked: boolean) => setIsShowPlan(checked)}
                    />
                  </Form.Item>
                  {isShowPlan ? (
                    <>
                      <Form.Item
                        name="time"
                        label="指导时间"
                        rules={[
                          {
                            required: true,
                            message: '请选择指导时间',
                          },
                        ]}
                      >
                        <DatePicker
                          name="time"
                          defaultValue={moment(moment().day(moment().day() + 7), 'YYYY-MM-DD')}
                          onChange={onChangetime}
                          disabledDate={(current) =>
                            (current && current < dayjs().endOf('day')) ||
                            current > moment().add(7, 'days')
                          }
                        />
                      </Form.Item>
                      <Form.Item
                        name="text"
                        label="备注"
                        rules={[
                          {
                            max: 100,
                            message: '最多输入100个字符',
                          },
                        ]}
                      >
                        <TextArea
                          name="text"
                          placeholder="请填写备注,最多100个字符"
                          rows={4}
                          onChange={onChangeRemark}
                        />
                      </Form.Item>
                    </>
                  ) : (
                    ''
                  )}
                </ProForm>
              </div>
              <div style={{ flex: 1 }}>
                <TextArea
                  style={{ marginLeft: '10px', resize: 'none' }}
                  onChange={onChangecontent}
                  name="text"
                  rows={5}
                  placeholder="请输入指导内容/记录/指导意见"
                  maxLength={100}
                />
              </div>
            </div>
          </>
        )}
      </div>
    </PageContainer>
  );
};
export default Audio;
